#include "qbuffer.h"

CharBuffer::CharBuffer(l64 capacity)
{
    if (mBuff) free(mBuff);

    mCapacity = capacity == 0 ? CAPDEF : capacity;
    mBuff = (char*)calloc(1, mCapacity);
}

CharBuffer::CharBuffer(const char* data, l64 len)
    : CharBuffer(CAPDEF)
{
    Put(data, len);
}

CharBuffer::CharBuffer(const std::string& data)
    : CharBuffer(data.data(), data.length())
{

}

CharBuffer::~CharBuffer()
{
    if (mBuff) {
        free(mBuff);
        mBuff = nullptr;
    }
}

SharedBuffer CharBuffer::Clone()
{
    SharedBuffer new_buff(new CharBuffer(mCapacity));

    new_buff->Put(mBuff, mLength);

    return new_buff;
}

CharBuffer& CharBuffer::Put(const char* data, l64 len)
{
    expand(len);

    memcpy(&mBuff[mLength], data, len);
    mLength += len;

    return *this;
}

CharBuffer& CharBuffer::Put(const std::string& data)
{
    return Put(data.data(), data.length());
}

CharBuffer& CharBuffer::Put(const CharBuffer& buff)
{
    return Put(buff.mBuff, buff.mLength);
}

l64 CharBuffer::Length()
{
    return mLength;
}

const char* CharBuffer::Get() const
{
    return mBuff;
}

char *CharBuffer::Get()
{
    return mBuff;
}

bool CharBuffer::IsNull()
{
    return mLength == 0;
}

bool CharBuffer::enoughDataReaded(l64 len)
{
    return (mLength - mDiff) >= len;
}

bool CharBuffer::enoughSpaceSave(l64 len)
{
    return (mCapacity - mLength) >= len;
}

void CharBuffer::diffForward(l64 len)
{
    mDiff += len;
}

void CharBuffer::expand(l64 len)
{
    if (!enoughSpaceSave(len)) {
        l64 cap = mCapacity + len;
        mCapacity = mFib.Next(cap);

        mBuff = (char*)realloc(mBuff, mCapacity);
    }
}
